package org.kernely.security.persistence;

import java.util.Set;

import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.JoinTable;
import javax.persistence.ManyToMany;
import javax.persistence.Table;

import org.hibernate.annotations.Cascade;

@Entity
@Table(name="kernely_group")
public class Group {
	@Id
	@GeneratedValue(strategy = GenerationType.AUTO)
	@Column(name="group_id")
	/**
	 * Group's id
	 */
	private int id;
	
	/**
	 * Group's name
	 */
	private String name;
	
	/**
	 * Users in the group
	 */
	@ManyToMany(cascade={CascadeType.PERSIST, CascadeType.MERGE}, fetch=FetchType.EAGER)
	@JoinTable( name="kernely_association_user_group",
				joinColumns=@JoinColumn(name="fk_group_association_user_group"),
				inverseJoinColumns=@JoinColumn(name="fk_user_association_user_group"))
	private Set<User> users;

	/**
	 * Roles of the group
	 */
    @ManyToMany(cascade={CascadeType.PERSIST, CascadeType.MERGE}, fetch=FetchType.EAGER)
	@JoinTable( name="kernely_group_roles",
				joinColumns=@JoinColumn(name="fk_group"),
				inverseJoinColumns=@JoinColumn(name="fk_role"))
    private Set<Role> roles;
    
    /**
	 * Permissions of the group
	 */
    @ManyToMany(fetch=FetchType.EAGER)
	@JoinTable( name="kernely_group_permissions",
				joinColumns=@JoinColumn(name="fk_group"),
				inverseJoinColumns=@JoinColumn(name="fk_permission"))
    @Cascade( { org.hibernate.annotations.CascadeType.ALL})
    private Set<Permission> permissions;
	
	/**
	 * @return the permissions
	 */
	public final Set<Permission> getPermissions() {
		return permissions;
	}

	/**
	 * @param permissions the permissions to set
	 */
	public final void setPermissions(Set<Permission> permissions) {
		this.permissions = permissions;
	}

	/**
	 * @return the roles
	 */
	public final Set<Role> getRoles() {
		return roles;
	}

	/**
	 * @param roles the roles to set
	 */
	public final void setRoles(Set<Role> roles) {
		this.roles = roles;
	}

	/**
	 * Get the group's ID
	 * @return the group's ID
	 */
	public final int getId() {
		return id;
	}

	/**
	 * Set the group's ID
	 * @param id : the group's ID
	 */
	public final void setId(int id) {
		this.id = id;
	}

	/**
	 * Get the group's name
	 * @return the group's name
	 */
	public final String getName() {
		return name;
	}

	/**
	 * Sets the group's name
	 * @param name : the group's name
	 */
	public final void setName(String name) {
		this.name = name;
	}

	/**
	 * Gets the users in the group.
	 * @return the users
	 */
	public final Set<User> getUsers() {
		return users;
	}

	/**
	 * Sets the users
	 * @param users the users to set
	 */
	public final void setUsers(Set<User> users) {
		this.users = users;
	}

	/* (non-Javadoc)
	 * @see java.lang.Object#hashCode()
	 */
	@Override
	public final int hashCode() {
		final int prime = 31;
		int result = 1;
		result = prime * result + id;
		result = prime * result + ((name == null) ? 0 : name.hashCode());
		return result;
	}

	/* (non-Javadoc)
	 * @see java.lang.Object#equals(java.lang.Object)
	 */
	@Override
	public final boolean equals(Object obj) {
		if (this == obj){
			return true;
		}
		if (obj == null){
			return false;
		}
		if (getClass() != obj.getClass()){
			return false;
		}
		Group other = (Group) obj;
		if (id != other.id){
			return false;
		}
		if (name == null) {
			if (other.name != null){
				return false;
			}
		} else if (!name.equals(other.name)){
			return false;
		}
		return true;
	}

		
}
